package awesomeProject

import (
	"fmt"
	"github.com/panjf2000/ants/v2"
	"log"
	"runtime"
	"sync"
	"time"
)

func GoroutineGo() {
	printEven := func() {
		for i := 2; i <= 10; i += 2 {
			fmt.Println(i)
			time.Sleep(time.Millisecond * 200)
		}
	}
	printOdd := func() {
		for i := 1; i <= 10; i += 2 {
			fmt.Println(i)
			time.Sleep(time.Millisecond * 200)
		}
	}
	fmt.Printf("%T\n", printEven)
	go printEven()
	go printOdd()
	time.Sleep(time.Second * 2)
}
func GoroutineWg() {
	wg := sync.WaitGroup{}
	printEven := func() {
		defer wg.Done()
		for i := 2; i <= 10; i += 2 {
			fmt.Println(i)
			time.Sleep(time.Millisecond * 200)
		}
	}
	printOdd := func() {
		defer wg.Done()
		for i := 1; i <= 10; i += 2 {
			fmt.Println(i)
			time.Sleep(time.Millisecond * 200)
		}
	}
	fmt.Printf("%T\n", printEven)
	wg.Add(1)
	go printEven()
	wg.Add(1)
	go printOdd()
	wg.Wait()
	fmt.Println("主goroutine已经等待所有子协程结束")
	time.Sleep(time.Second * 2)
}

func GoroutineRandome() {
	wg := sync.WaitGroup{}
	for i := 1; i <= 10; i++ {
		wg.Add(1)
		go func(n int) {
			defer wg.Done()
			fmt.Println(n)
		}(i)
	}
	wg.Wait()
	fmt.Println("主goroutine 执行结束")
}

func GoroutineNum() {
	go func() {
		for {
			fmt.Println("goroutineNum=", runtime.NumGoroutine())
			time.Sleep(time.Millisecond * 500)
		}
	}()

	for {
		go func() {
			fmt.Println("hello")
			time.Sleep(time.Second * 10)
		}()
	}
}
func GoroutineAnts() {
	go func() {
		for {
			fmt.Println("goroutineNum=", runtime.NumGoroutine())
			time.Sleep(time.Millisecond * 500)
		}
	}()
	size := 1024
	pool, err := ants.NewPool(size)
	defer pool.Release()
	if err != nil {
		log.Fatalln(err)
	}
	for {
		err := pool.Submit(func() {
			time.Sleep(10 * time.Second)
		})
		if err != nil {
			log.Fatalln(err)
		}
	}
}
func GoroutineSched() {
	wg := sync.WaitGroup{}
	wg.Add(1)
	go func() {
		defer wg.Done()
		for i := 1; i <= 100; i += 2 {
			fmt.Println(i)
			runtime.Gosched()
			//time.Sleep(time.Millisecond * 1)
		}

	}()
	wg.Add(1)
	go func() {
		defer wg.Done()
		for i := 2; i <= 100; i += 2 {
			fmt.Println(i)
			runtime.Gosched()
			//time.Sleep(time.Millisecond * 1)
		}
	}()
	wg.Wait()
}

func GoroutineAsync() {
	ch := make(chan int, 5)
	wg := sync.WaitGroup{}
	wg.Add(1)
	go func() {
		defer wg.Done()
		defer close(ch)
		for i := 1; i <= 5; i++ {
			ch <- i
			fmt.Println("put a val = ", i)
			time.Sleep(time.Millisecond * 200)
		}

	}()
	wg.Add(1)
	go func() {
		defer wg.Done()
		for val := range ch {
			fmt.Println("get a val=", val)
		}
	}()
	wg.Wait()
}
